package com.sc.service.impl;

import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.spring.service.impl.CacheableServiceImpl;
import com.sc.dto.EmpRoleUpdateDTO;
import com.sc.entity.Emp;
import com.sc.entity.EmpRole;
import com.sc.exception.ServiceException;
import com.sc.mapper.EmpMapper;
import com.sc.mapper.EmpRoleMapper;
import com.sc.service.EmpRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;

import static com.sc.entity.table.EmpTableDef.EMP;

/**
 * 员工-角色关系表 服务层实现。
 *
 * @author JoeZhou
 * @since 2024-09-11
 */
@Service
@CacheConfig(cacheNames = "empRole")
public class EmpRoleServiceImpl extends CacheableServiceImpl<EmpRoleMapper, EmpRole> implements EmpRoleService {

    @Autowired
    private EmpMapper empMapper;

    @Override
    @CacheEvict(allEntries = true)
    @Transactional
    public boolean updateEmpRoles(EmpRoleUpdateDTO dto) {
        if (empMapper.selectCountByQuery(QueryWrapper.create().eq("id", dto.getEmpId())) == 0){
            throw new ServiceException("员工信息不存在~");
        }
        Collections.sort(dto.getRoleIds());
        // 删除原有角色
        this.remove(QueryWrapper.create().eq("emp_id", dto.getEmpId()));
        List<EmpRole> empRoles = new LinkedList<>();
        // 给员工分配角色
        dto.getRoleIds().forEach(roleId -> {
            EmpRole relation = new EmpRole(dto.getEmpId(), roleId);
            empRoles.add(relation);
        });
        return this.saveBatch(empRoles);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean remove(QueryWrapper query) {
        return super.remove(query);
    }

    @Override
    @CacheEvict(key = "#id")
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean removeByIds(Collection<? extends Serializable> ids) {
        return super.removeByIds(ids);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean update(EmpRole entity, QueryWrapper query) {
        return super.update(entity, query);
    }

    @Override
    @CacheEvict(key = "#entity.id")
    public boolean updateById(EmpRole entity, boolean ignoreNulls) {
        return super.updateById(entity, ignoreNulls);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean updateBatch(Collection<EmpRole> entities, int batchSize) {
        return super.updateBatch(entities, batchSize);
    }

    @Override
    @Cacheable(key = "#id")
    public EmpRole getById(Serializable id) {
        return super.getById(id);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public EmpRole getOne(QueryWrapper query) {
        return super.getOne(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> R getOneAs(QueryWrapper query, Class<R> asType) {
        return super.getOneAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public Object getObj(QueryWrapper query) {
        return super.getObj(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> R getObjAs(QueryWrapper query, Class<R> asType) {
        return super.getObjAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public List<Object> objList(QueryWrapper query) {
        return super.objList(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> List<R> objListAs(QueryWrapper query, Class<R> asType) {
        return super.objListAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public List<EmpRole> list(QueryWrapper query) {
        return super.list(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> List<R> listAs(QueryWrapper query, Class<R> asType) {
        return super.listAs(query, asType);
    }

    /**
     * @deprecated 无法通过注解进行缓存操作。
     */
    @Override
    @Deprecated
    public List<EmpRole> listByIds(Collection<? extends Serializable> ids) {
        return super.listByIds(ids);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public long count(QueryWrapper query) {
        return super.count(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #page.getPageSize() + ':' + #page.getPageNumber() + ':' + #query.toSQL()")
    public <R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType) {
        return super.pageAs(page, query, asType);
    }

}
